# @Version : 1.0
# @Author  : wxz
# @File    : access_token_verify.py
# @Time    : 2025/6/7 15:48
# @Describe: 描述...
import time

from jose import jwt, ExpiredSignatureError
from starlette.responses import JSONResponse

from config.app_logger import logger
from utils.jwt import JWT


class AccessTokenVerify:

    @classmethod
    async def verify_access_token(cls, authorization: str):

        try:
            logger.info(f"从Header请求头中获取token: {authorization}")
            # 如果未获取到Token令牌，则抛出异常
            if authorization is None:
                # OAuth2规范，如果认证失败，请求头中返回 "WWW-Authenticate"
                return no_access_token_response()
            # 进行Token令牌校验
            access_token = authorization.split(' ')[1]

            subject: dict = jwt.decode(
                token=access_token,
                key=JWT.JWT_SECRET_KEY,
                algorithms=["HS256"],
            )

            # 判断令牌是否过期
            expires_delta = subject.get("exp")
            if expires_delta is None:
                return lack_user_response()
            # 如果令牌过期，则重新登录
            elif expires_delta <= int(time.time()):
                return expire_token_response()

            # 获取用户ID
            user_id = subject.get("sub")
            # 缺失用户信息
            if user_id is None:
                return lack_user_response()

            return user_id
        except ExpiredSignatureError as exp:  # 令牌过期
            logger.error(exp, exc_info=True)
            return expire_token_response()

        except Exception as e:
            logger.error(e, exc_info=True)
            return token_exception_response()

def no_access_token_response():
    return JSONResponse(
        status_code=401,
        content={"code": 111111, "message": "未获取到访问令牌", "data": None},
        headers={"WWW-Authenticate": "Bearer"},
    )

def lack_user_response():
    return JSONResponse(
        status_code=401,
        content={"code": 222222, "message": "缺失用户信息", "data": None},
        headers={"WWW-Authenticate": "Bearer"},
    )

def token_exception_response():
    return JSONResponse(
        status_code=401,
        content={"code": 333333, "message": "访问令牌异常", "data": None},
        headers={"WWW-Authenticate": "Bearer"},
    )

def expire_token_response():
    return JSONResponse(
        status_code=401,
        content={"code": 444444, "message": "令牌过期，请重新登录", "data": None},
        headers={"WWW-Authenticate": "Bearer"},
    )
